import {Accrual, Category, Voucher} from 'cascadium-ledger';

const recategorize = (category, journalVouchers) => {

  const decompVoucherEntries = journalVouchers.map(({succ}) => succ).flat();

  const gatheredByCate = decompVoucherEntries
  .grip('curr.code')
  .grap(([, entries]) => {

    const gatheredByDest = entries
      .grip('dest.code')
      .grap(([, entries]) => {

        const gatheredByDir = entries
        .grip(({accrual}) => accrual.dir())
        .grap(([dir, entries]) => {
          const voucher = Voucher.from(entries, {voucherID: undefined});
          Object.assign(voucher.attr, {level: 'DIRECTION', dir});
          return voucher;
        })

        const voucher = Voucher.from(gatheredByDir, {voucherID: undefined})
        voucher.attr.level = 'DEST_CATE';

        return voucher;
      });
    return Voucher.from(gatheredByDest);
  })
  .flat();
 
  const categoryEnds = category.unnestTo().all('succ.length', 0);

  categoryEnds.mergeFrom(gatheredByCate, {
    mergeKey: 'curr.code',
    mergeFunc: ({source, target}) => {

      const {succ: destCates} = source;
      for (let i = destCates.length - 1; i >= 0; i --) destCates[i].move(target);
      target.accrual = source.accrual;
      target.attr.level = 'END_CATE';
      target.attr.style = 'balance';
    }
  });

  for (let {succ: destCates} of gatheredByCate) {
    for (let destCate of destCates) {
      if (!(destCate.pred instanceof Category)) {
        console.warn('UNMERGED DEST', destCate);
      }
    }
  }
}

export default recategorize;